package com.vids.controller;


import cn.hutool.core.text.CharSequenceUtil;
import com.vids.constant.Urlconstant;
import com.vids.constant.VIIDRespEnum;
import com.vids.model.entity.Ape;
import com.vids.model.param.ApeBatchParam;
import com.vids.service.IApeService;
import com.vids.utils.BeanUtilss;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.vids.model.response.ResponseStatus;

/**
 * <p>
 * 采集设备表 前端控制器
 * </p>
 *
 */
@Slf4j
@RestController
@RequestMapping("/VIID")
@RequiredArgsConstructor
public class ApeController  {

    private final IApeService apeService;

    /**
     * 修改采集设备
     *
     * @param param
     * @return
     * @throws Exception
     */
    @PutMapping(value = "/APEs", produces = "application/VIID+JSON")
    public Object updateApes(@RequestBody ApeBatchParam param) throws Exception {
	List<ResponseStatus> resps = new ArrayList<ResponseStatus>();
	if (param == null || param.getAPEListObject() == null || param.getAPEListObject().getAPEObject() == null
		|| param.getAPEListObject().getAPEObject().size() == 0) {
	    ResponseStatus status = new ResponseStatus(Urlconstant.URL_APES, VIIDRespEnum.OK.getCode(), new Date());
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "参数为空；");
	    resps.add(status);
	    return new ResponseEntity<>(
                BeanUtilss.objectToMap(BeanUtilss.getBatchResponseModel(resps)), HttpStatus.CREATED);
	}
	List<Ape> list = param.getAPEListObject().getAPEObject();
	for (Ape vo : list) {
	    ResponseStatus status = new ResponseStatus(Urlconstant.URL_APES, VIIDRespEnum.OK.getCode(), new Date());
	    // 1.校验参数
	    try {
		validateParams(vo, status);
		if (status.getStatusCode().equals(VIIDRespEnum.OK.getCode())) {
		    Ape ape = apeService.getById(vo.getApeID());
		    if (ape == null) {
			status.setStatusString(VIIDRespEnum.INVALID_JSON_CONTENT.getMsg() + "[" + "资源不存在" + "]");
			status.setStatusCode(VIIDRespEnum.INVALID_JSON_CONTENT.getCode());
		    } else {
			vo.setId(ape.getId());
			apeService.updateApe(vo);
			status.setStatusString("修改成功");
		    }
		}
	    } catch (Exception e) {
		status.setStatusString(VIIDRespEnum.DEVICE_ERROR.getMsg() + "[" + "请联系管理员" + "]");
		status.setStatusCode(VIIDRespEnum.DEVICE_ERROR.getCode());
		log.error("createGatherDevices Exception" + vo.toString(), e);
	    }
	    resps.add(status);
	}
	return new ResponseEntity<>(BeanUtilss.objectToMap(BeanUtilss.getBatchResponseModel(resps)),
            HttpStatus.CREATED);
    }

    /**
     * 验证参数
     *
     * @param vo
     * @return
     */
    private void validateParams(Ape vo, ResponseStatus status) {
	if (CharSequenceUtil.isEmpty(vo.getApeID())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "设备编码ApeID必填");
	} else if (vo.getApeID().length() != 20) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "设备编码ApeID长度为20");
	} else if (!vo.getApeID().matches("^[0-9]+$")) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "ApeID的组成必为纯数字");
	} else if (CharSequenceUtil.isEmpty(vo.getName())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "设备名称Name必填");
	} else if (vo.getName().length() > 100) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "设备名称Name长度不能超过100字符");
	} else if (CharSequenceUtil.isEmpty(vo.getModel())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "设备型号Model必填");
	} else if (vo.getModel().length() > 100) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "设备型号Model长度不能超过100字符");
	} else if (CharSequenceUtil.isEmpty(vo.getIPAddr())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "IPAddr必填");
	} else if (vo.getIPAddr().length() > 30 || !this.checkIP(vo.getIPAddr())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "IPAddr不合法");
	} else if (CharSequenceUtil.isNotEmpty(vo.getIPV6Addr()) && vo.getIPV6Addr().length() > 64) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "IPAddr长度不能超过64个字符");
	} else if (CharSequenceUtil.isNotBlank(vo.getIPV6Addr()) && !this.checkIPV6(vo.getIPV6Addr())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "IPV6Addr不合法");
	} else if (vo.getPort() == null) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "端口号Port必填");
	} else if (vo.getPort() < 0 || vo.getPort() > 65535) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "端口号Port取值范围[0,65535]");
	} else if (vo.getLongitude() == null) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "经度Longitude必填");
	} else if (!this.checkLongitude(vo.getLongitude().toString())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "经度Longitude不合法");
	} else if (vo.getLatitude() == null) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "纬度Latitude必填");
	} else if (!this.checkLatitude(vo.getLatitude().toString())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "纬度Latitude不合法");
	} else if (CharSequenceUtil.isEmpty(vo.getPlaceCode())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "安装地点行政区划PlaceCode必填");
	} else if (vo.getPlaceCode().length() != 6) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "安装地点行政区划PlaceCode长度不为6");
	} else if (!vo.getPlaceCode().matches("^[0-9]+$")) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "安装地点行政区划为纯数字");
	}
    else if (CharSequenceUtil.isNotEmpty(vo.getPlace()) && vo.getPlace().length() > 256) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "安装地点Place字段长度不能超过256个字符");
	} else if (vo.getCapDirection() != null && (vo.getCapDirection() != 0 && vo.getCapDirection() != 1)) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "车辆抓拍方向CapDirection不是字典值");
	} else if (vo.getMonitorAreaDesc() != null && vo.getMonitorAreaDesc().length() > 256) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "监视区域说明MonitorAreaDesc长度不能超过256个字符");
	} else if (CharSequenceUtil.isEmpty(vo.getIsOnline())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "是否在线IsOnline必填");
	} else if (vo.getIsOnline().length() != 1) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "是否在线IsOnline字典长度不为1个字符");
	} else if (!Arrays.asList("1", "2", "9").contains(vo.getIsOnline())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "是否在线IsOnline取值为{1,2,9}");
	} else if (CharSequenceUtil.isNotBlank(vo.getUserId()) && vo.getUserId().length() > 64) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "登录账号UserId必填/不能超过64个字符");
	} else if (CharSequenceUtil.isNotBlank(vo.getPassword()) && vo.getPassword().length() > 32) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "登录密码Password必填/不能超过32个字符");
	} else if (CharSequenceUtil.isNotBlank(vo.getOrgCode()) && vo.getOrgCode().length() != 12) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "管辖单位代码的长度为12");
	} else if (CharSequenceUtil.isNotBlank(vo.getOrgCode()) && !vo.getOrgCode().matches("^[0-9]+$")) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "管辖单位代码为纯数字");
	} else if (vo.getMonitorDirection() != null
		&& !Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).contains(vo.getMonitorDirection())) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "监视区域不在字典范围");
	} else if (CharSequenceUtil.isNotBlank(vo.getOwnerApsID()) && vo.getOwnerApsID().length() != 20) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "所属采集系统OwnerApsID长度为20");
	} else if (CharSequenceUtil.isNotBlank(vo.getOwnerApsID()) && !vo.getOwnerApsID().matches("^[0-9]+$")) {
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "所属采集系统OwnerApsID的组成必为纯数字");
	}
    }

    /**
     * 经度校验 经度longitude: (?:[0-9]|[1-9][0-9]|1[0-7][0-9]|180)\\.([0-9]{6})
     * 
     * @return
     */
    public boolean checkLongitude(String longitude) {
	java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
	nf.setGroupingUsed(false);
	nf.setMinimumFractionDigits(0);
	nf.setMaximumFractionDigits(6);
	String reglo = "^(\\-|\\+)?(((\\d|[1-9]\\d|1[0-7]\\d|0{1,3})\\.\\d{0,9})|(\\d|[1-9]\\d|1[0-7]\\d|0{1,3})|180\\.0{0,9}|180)$";
	longitude = longitude.trim();
	longitude = nf.format(new Double(longitude));
	return longitude.matches(reglo);
    }

    /**
     * 纬度校验 纬度latitude： (?:[0-9]|[1-8][0-9]|90)\\.([0-9]{6})
     * 
     * @return
     */
    public boolean checkLatitude(String latitude) {
	java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
	nf.setGroupingUsed(false);
	nf.setMinimumFractionDigits(0);
	nf.setMaximumFractionDigits(6);
	String regla = "^(\\-|\\+)?([0-8]?\\d{1}\\.\\d{0,9}|90\\.0{0,9}|[0-8]?\\d{1}|90)$";
	latitude = latitude.trim();
	latitude = nf.format(new Double(latitude));
	return latitude.matches(regla);
    }

    /**
     * IP校验
     * 
     * @return
     */
    public boolean checkIP(String ip) {
	// ip的正则表达式
	String ipReg = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$";
	Pattern ipPattern = Pattern.compile(ipReg);
	return ipPattern.matcher(ip).matches();
    }

    /**
     * IPV6校验
     * 
     * @return
     */
    public boolean checkIPV6(String ip) {
	String ipV6Reg = "(^((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4}){1}|:))"
		+ "|(([0-9A-Fa-f]{1,4}:){6}((:[0-9A-Fa-f]{1,4}){1}|" + "((22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|"
		+ "([0-9]){1,2})([.](25[0-5]|2[0-4][0-9]|" + "[0-1][0-9][0-9]|([0-9]){1,2})){3})|:))|"
		+ "(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|" + ":((22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|"
		+ "([0-9]){1,2})([.](25[0-5]|2[0-4][0-9]|" + "[0-1][0-9][0-9]|([0-9]){1,2})){3})|:))|"
		+ "(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}" + "|:((22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|"
		+ "([0-9]){1,2})([.](25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|"
		+ "([0-9]){1,2})){3})|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|"
		+ ":((22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|" + "([0-9]){1,2})([.](25[0-5]|2[0-4][0-9]|"
		+ "[0-1][0-9][0-9]|([0-9]){1,2})){3})|:))|" + "(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|"
		+ ":((22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|" + "([0-9]){1,2})([.](25[0-5]|2[0-4][0-9]|"
		+ "[0-1][0-9][0-9]|([0-9]){1,2})){3})|:))" + "|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}"
		+ "|:((22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|" + "([0-9]){1,2})([.](25[0-5]|2[0-4][0-9]|"
		+ "[0-1][0-9][0-9]|([0-9]){1,2})){3})|:))|"
		+ "(:((:[0-9A-Fa-f]{1,4}){1,7}|(:[fF]{4}){0,1}:((22[0-3]|2[0-1][0-9]|" + "[0-1][0-9][0-9]|([0-9]){1,2})"
		+ "([.](25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|([0-9]){1,2})){3})|:)))$)";
	Pattern ipPattern = Pattern.compile(ipV6Reg);
	return ipPattern.matcher(ip).matches();
    }

    /**
     * 添加采集设备
     * 
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/APEs", produces = "application/VIID+JSON")
    public Object createGatherDevices(@RequestBody ApeBatchParam param) throws Exception {
	List<ResponseStatus> resps = new ArrayList<ResponseStatus>();
	if (param == null || param.getAPEListObject() == null || param.getAPEListObject().getAPEObject() == null
		|| param.getAPEListObject().getAPEObject().size() == 0) {
	    ResponseStatus status = new ResponseStatus(Urlconstant.URL_APES, VIIDRespEnum.OK.getCode(), new Date());
	    setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "参数为空；");
	    resps.add(status);
	    return new ResponseEntity<Map<String, Object>>(
		    BeanUtilss.objectToMap(BeanUtilss.getBatchResponseModel(resps)), HttpStatus.CREATED);
	}
	List<Ape> list = param.getAPEListObject().getAPEObject();
	for (Ape ape : list) {
	    ResponseStatus status = new ResponseStatus(Urlconstant.URL_APES, VIIDRespEnum.OK.getCode(), new Date());
	    try {
		validateParams(ape, status);
		ape.setId(null);
		if (status.getStatusCode() == VIIDRespEnum.OK.getCode()
			|| status.getStatusCode() == VIIDRespEnum.OK.getCode()) {
		    Ape result = apeService.getById(ape.getApeID());
		    if (result != null) {
			setStatus(status, VIIDRespEnum.INVALID_JSON_CONTENT, "资源已存在");
		    } else {
			String id = apeService.insertDevice(ape);
			status.setStatusString("保存成功");
			status.setId(id);
		    }
		}
	    } catch (Exception e) {
		setStatus(status, VIIDRespEnum.DEVICE_ERROR, "请联系管理员");
		log.error("createGatherDevices Exception" + ape.toString(), e);
	    }
	    resps.add(status);
	}
	return new ResponseEntity<Map<String, Object>>(BeanUtilss.objectToMap(BeanUtilss.getBatchResponseModel(resps)),
		HttpStatus.CREATED);
    }

    /**
     * 查询采集设备
     *
     * @return
     */
    @GetMapping(value = "/APEs", produces = "application/VIID+JSON;charset=UTF-8")
    public Object getList(HttpServletRequest request) {
	Object attribute = request.getAttribute("map");
	ApeBatchParam param = null;
	if (attribute instanceof Map) {
	    Map<String, Object> map = (Map<String, Object>) attribute;
	    param = apeService.getDeviceList(map);
	}
	if (param == null) {
	    return new ResponseEntity<Map<String, Object>>(new HashMap<String, Object>(), HttpStatus.NO_CONTENT);
	}
	return param;
    }

    protected void setStatus(com.vids.model.response.ResponseStatus res, VIIDRespEnum e, String field) {
        StringBuffer sb = new StringBuffer();
        sb.append(e.getMsg() + "[" + field + "]");
        res.setStatusCode(e.getCode());
        res.setStatusString(sb.toString());
    }
}
